import asyncio
import os
import platform

from aiohttp import web

from src.dicom_viewer_be_mock_xiaosai.common.exception import ValidationError
from src.dicom_viewer_be_mock_xiaosai.type import EnumOpType, EnumViewMode
from src.dicom_viewer_be_mock_xiaosai.utils.helper import convert_windows_path_to_container_path
from src.dicom_viewer_be_mock_xiaosai.loader.DicomLoader import DicomLoader
from src.dicom_viewer_be_mock_xiaosai.service.api_middleware import api_response, APIResponse, logger
from src.dicom_viewer_be_mock_xiaosai.utils.util import extract_sequence_structure

from src.dicom_viewer_be_mock_xiaosai.loader.ImgLoader import ImgLoader
from src.dicom_viewer_be_mock_xiaosai.share import img_loader_dict
from src.dicom_viewer_be_mock_xiaosai.type import EnumViewType
from src.dicom_viewer_be_mock_xiaosai.utils import helper
from src.dicom_viewer_be_mock_xiaosai.components.ViewGroupManager import ViewGroupManager
from system_config import config

# 创建 aiohttp 应用
app = web.Application()


def get_img_loader(group_or_view_id):
    img_loader = img_loader_dict.get(group_or_view_id, None)
    if img_loader is None:
        raise ValidationError('viewId 不存在,没有生成对应的loader')
    return img_loader


@api_response
async def resolve_folder(request):
    json_request = await request.json()
    relative_path = json_request["relativePath"]
    request_path_prefix =  config["request_path_prefix"]
    if platform.system() == 'Windows':
        folder_path = request_path_prefix + relative_path
    else:
        folder_path =  config['docker_dicom_folder_prefix'] + convert_windows_path_to_container_path(relative_path)
    logger.info(f"resolve folder_path is:{folder_path}")
    patient_record_dict, series_record_dict, ds_arr = helper.analyze_dicom_folder(folder_path=folder_path)
    asyncio.create_task(DicomLoader.classify_ds_arr(ds_arr))
    return {
            "patientRecord": patient_record_dict,
            "seriesRecord": series_record_dict
        }



@api_response
async def load_series(request):
    json_request = await request.json()
    group_id = json_request['groupId']
    series_id = json_request['seriesId']
    
    if group_id in img_loader_dict:
        img_loader = img_loader_dict[group_id]
    else:
        img_loader = ImgLoader(group_id)
        img_loader_dict[group_id] = img_loader



    if "subViewIds" in json_request:
        sub_view_ids = json_request['subViewIds']
        ViewGroupManager.parse_and_bind_ids(group_id, sub_view_ids)
    else:
        sub_view_ids = None
    await  img_loader.load_dicom_at_once(series_id)

    series_base_info = img_loader.dicom_tag_info.tags
    if sub_view_ids is not None:
        return {
            "groupId": group_id,
            "subViewIds": sub_view_ids,
            "series_base_info": series_base_info
        }
    return  {
            "groupId": group_id,
            "series_base_info": series_base_info
    }


@api_response
async def set_size(request):
    json_request = await request.json()
    size = json_request['size']
    view_id = json_request['viewId']
    view_type = json_request['viewType']
    img_loader = get_img_loader(view_id)
    match view_type:
        case EnumViewType.stack.value:
            width = size['width']
            height = size['height']
            asyncio.create_task(img_loader.set_stack_size(view_id, (height, width)))
        case EnumViewType.Ax.value | EnumViewType.Sag.value | EnumViewType.Cor.value :
            asyncio.create_task(img_loader.set_mpr_viewer_size(view_id,view_type,size))
        case EnumViewType.Volume.value:
            width = size['width']
            height = size['height']
            img_loader.set_volume_viewer_size((width, height))
            asyncio.create_task(img_loader.get_view(EnumViewType.Volume.value))
    return APIResponse.success()

@api_response
async def handle_play(request):
    json_request = await request.json()
    group_id = json_request['viewId']
    img_loader = get_img_loader(group_id)

    view_id = json_request['viewId']
    view_type = json_request['viewType']
    view_mode = json_request['viewMode']
    play_setting = json_request['playSetting']
    asyncio.create_task(img_loader.handle_op({
        "viewId": view_id,
        "groupId": group_id,
        "viewType": view_type,
        "viewMode": view_mode,
        "opType": EnumOpType.play.value,
        "play_setting": play_setting
    }))
    return APIResponse.success()







@api_response
async def resolve_tags(request):
    json_request = await request.json()
    series_id = json_request["seriesId"]
    index = int(json_request["index"])
    ds_arr = DicomLoader.series_dict[series_id]
    tags_info = extract_sequence_structure(ds_arr[index])
    return {
        "tagsInfo": tags_info
    }


async def modify_dicom(request):
    json_request = await request.json()
    series_id = json_request["seriesId"]
    tag_info_arr = json_request["tagInfo"]
    dicom_index = int(json_request["dicomIndex"])
    save_folder_path = json_request['saveFilePath']
    filename_arr = DicomLoader.series_filename_dict[series_id]
    ds_arr = DicomLoader.series_dict[series_id]
    if ds_arr is None:
        return APIResponse.error("series id error")
    ds  = ds_arr[dicom_index]

    for tag_info in tag_info_arr:
        dicom_tag_id_str = tag_info['tagId']
        clean_str = dicom_tag_id_str.strip('()').replace(' ', '')
        parts = clean_str.split(',')
        dicom_tag_id_number = [int(part, 16) for part in parts]
        ds[dicom_tag_id_number].value = tag_info['value']

    save_file_path = save_folder_path + '\\' + filename_arr[dicom_index]
    counter = 1

    # 检查文件是否存在，如果存在则添加序号
    while os.path.exists(save_file_path):
        name, ext = os.path.splitext(save_file_path)
        save_file_path = f"{name}_{counter}{ext}"
        counter += 1
    ds.save_as(save_file_path)
    return APIResponse.success()


async def modify_series(request):
    return web.json_response(
        {
            "message": "ok",
        })


@api_response
async def set_window(request):
    json_request = await request.json()
    view_id = json_request['viewId']
    group_id = json_request['groupId']
    view_type = json_request['viewType']
    view_mode = json_request['viewMode']
    img_loader = get_img_loader(view_id)
    asyncio.create_task(img_loader.handle_op({
        "viewId": view_id,
        "groupId": group_id,
        "viewType": view_type,
        "viewMode": view_mode,
        "opType": EnumOpType.set_window.value,
        "window_width":json_request['windowWidth'],
        "window_center":json_request['windowCenter'],
    }))
    return APIResponse.success()


async def handle_mip_setting(request):
    json_request = await request.json()
    group_id = json_request['groupId']
    img_loader = get_img_loader(group_id)
    mip_setting = json_request['mipSetting']
    asyncio.create_task(img_loader.handle_op({
        "viewId": '',
        "groupId": group_id,
        "viewType": EnumViewType.MPR.value,
        "viewMode": EnumViewMode.normal.value,
        "opType": EnumOpType.set_mip.value,
        "mip_setting":mip_setting,
    }))
    return APIResponse.success()



@api_response
async def set_invert(request):
    json_request = await request.json()
    view_id = json_request['viewId']
    group_id = json_request['groupId']
    view_type = json_request['viewType']
    view_mode = json_request['viewMode']
    img_loader = get_img_loader(group_id)
    ViewGroupManager.set_group_config(group_id,'invert', json_request['value'])
    asyncio.create_task(img_loader.handle_op({
        "viewId": view_id,
        "groupId": group_id,
        "viewType": view_type,
        "opType": EnumOpType.get_img.value,
        "viewMode":view_mode
    }))
    return APIResponse.success()


app.router.add_post('/resolveFolder', resolve_folder)
app.router.add_post('/loadSeries', load_series)
app.router.add_post('/setSize', set_size)
app.router.add_post('/play', handle_play)
app.router.add_post('/scrollAStep', handle_play)

app.router.add_post('/getTags', resolve_tags)
app.router.add_post('/modifyDicom', modify_dicom)
app.router.add_post('/modifySeries', modify_series)


app.router.add_post('/setWindow', set_window)
app.router.add_post('/setInvertWhite', set_invert)

app.router.add_post('/mipSetting', handle_mip_setting)





